﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;


namespace Skybot.Base.Connect
{
    /// <summary>
    /// 协议接收数据解析
    /// </summary>
    /// <![CDATA[
    /// 1.初始化2拆包线程
    /// 2.初始化4解析线程
    /// ]]>
    public class TaskReceiverProtocolResolve
    {
        /// <summary>
        /// 线程通知应答
        /// </summary>
        private CancellationTokenSource tasksource = null;
        /// <summary>
        /// 线程任务
        /// </summary>
        private Task task;
        /// <summary>
        /// 开始解析数据指令
        /// </summary>
        /// <returns>如果成功返回true</returns>
        public bool Start()
        {
            //多线程处理
            if (task == null || task.IsCanceled || task.IsCompleted || task.IsFaulted)
            {
                tasksource = new CancellationTokenSource();
                CancellationToken token = tasksource.Token;
                var task1 = new TaskEx(SplictProtocol, token) { ThreadName = "接收协议拆包线程" };
                task = task1;
                task.Start();

                //4线程解析队列
                var task2 = new TaskEx(ResolveProtocol, token) { ThreadName = "接收协议解析线程" }; ;
                task2.Start();

                //添加到线程管理
                ThreadManager.Instance.Add(task1);
                ThreadManager.Instance.Add(task2);
                return true;
            }
            else
            {
                System.Console.WriteLine("InCom.OTM服务端模式接收器当前正经进行开始解析指令,请不要重复调用");
                System.Diagnostics.Debug.WriteLine("InCom.OTM服务端模式接收器当前正经进行开始解析指令,请不要重复调用");
            }
            return false;
        }

        /// <summary>
        /// 停止解析线程
        /// </summary>
        /// <returns></returns>
        public bool Stop()
        {
            tasksource.Cancel();
            task = null;
            return true;
        }

        /// <summary>
        /// 解析协议
        /// </summary>
        /// <param name="obj"></param>
        private void SplictProtocol(object obj)
        {
            while (true)
            {
                //协议拆包
                DoSplicts();
            }
        }

        /// <summary>
        /// 解析协议
        /// </summary>
        /// <param name="obj"></param>
        private void ResolveProtocol(object obj)
        {
            while (true)
            {
                //解析协议
                DoResolve();
            }
        }
        
        /// <summary>
        /// 添加一个接收器
        /// </summary>
        public void Push(TCPReceiver receive)
        {
            lock (receivesSplicts)
            {
                receivesSplicts.Enqueue(receive);
            }
        }
        
        /// <summary>
        /// 用于处理协议的队列
        /// </summary>
        ConcurrentQueue<TCPReceiver> receivesSplicts = new ConcurrentQueue<TCPReceiver>();

        /// <summary>
        /// 等待解析协议
        /// </summary>
        ConcurrentQueue<TCPReceiver> ParseRceeives = new ConcurrentQueue<TCPReceiver>();
        
        /// <summary>
        /// 开始协议拆包
        /// </summary>
        public void DoSplicts()
        {
            if (receivesSplicts.Count > 0)
            {
                TCPReceiver rec = null;
                receivesSplicts.TryDequeue(out rec);
                if (rec != null)
                {
                    if (rec.ReceiveByteArrayQueue.Count > 0)
                    {
                        for (; rec.ReceiveByteArrayQueue.Count > 0; )
                        {
                            //拆包
                            rec.ProcessBytes(false);
                        }
                        //拆包完成后加入到等待解析队列
                        lock (ParseRceeives)
                        {
                            ParseRceeives.Enqueue(rec);
                        }
                    }
                }
            }
            else
            {
                System.Threading.Thread.Sleep(50);
            }
        }

        /// <summary>
        /// 开始解析协议
        /// </summary>
        public void DoResolve()
        {
            if (ParseRceeives.Count > 0)
            {
                TCPReceiver rec = null;
                ParseRceeives.TryDequeue(out rec);
                if (rec != null)
                {
                    if (rec.ProtocolEntityQueue.Count > 0)
                    {
                        for (; rec.ProtocolEntityQueue.Count > 0; )
                        {
                            //解析
                            rec.ParsePortocolItem(false);
                        }
                    }
                }
            }
            else
            {
                System.Threading.Thread.Sleep(50);
            }
        }

    }
}
